package org.jeecg.modules.wflow.service.impl;

import cn.hutool.core.util.ObjectUtil;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.api.model.SysDepartVO;
import org.jeecg.common.system.api.model.SysUser;
import org.jeecg.common.system.api.model.SysUserVO;
import org.jeecg.modules.wflow.bean.do_.DeptDo;
import org.jeecg.modules.wflow.bean.do_.RoleDo;
import org.jeecg.modules.wflow.bean.do_.UserDeptDo;
import org.jeecg.modules.wflow.bean.do_.UserDo;
import org.jeecg.modules.wflow.bean.vo.ModelGroupVo;
import org.jeecg.modules.wflow.bean.vo.OrgTreeVo;
import org.jeecg.modules.wflow.mapper.*;
import org.jeecg.modules.wflow.service.OrgRepositoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;


@Service("jeecgOrgRepositoryService")
@Slf4j
public class DHHSOrgRepositoryServiceImpl implements OrgRepositoryService {

    @Autowired
    private WflowDepartmentsMapper departsMapper;

    @Autowired
    private WflowUserDepartmentsMapper userDepartmentsMapper;
    
    @Autowired
    private WflowModelPermsMapper modelPermsMapper;

    @Autowired
    ISysBaseAPI sysBaseAPI;

    @Autowired
    @Qualifier("defaultOrgRepositoryService")
    private OrgRepositoryService defaultOrgRepositoryServiceImpl;

    @Override
    public List<ModelGroupVo.Form> getModelsByPerm(String userId) {
        //修改逻辑
        List<String> orgIds = sysBaseAPI.getDepIdByUser(userId).getResult();
        orgIds.add(userId);
        List<String> formIds = new ArrayList<>();
        List<ModelGroupVo.Form> result = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(orgIds)){
            formIds = modelPermsMapper.selectFormIdsByOrgId(orgIds);
        }
        if(ObjectUtil.isNotEmpty(formIds)){
            result = modelPermsMapper.selectByFormIds(formIds);
        }else{
            result = modelPermsMapper.selectNotInFormId();
        }
        return result;
        //原逻辑
//        return defaultOrgRepositoryServiceImpl.getModelsByPerm(userId);
    }

    /**
     * find by id
     *
     * @param userId 用户ID
     * @return
     */
    @Override
    public UserDo getUserById(String userId) {
        Result<SysUser> sysUserResult = sysBaseAPI.queryUserById(userId);
        SysUser result = sysUserResult.getResult();
        return UserDo.builder().userId(result.getId()).userName(result.getRealname()).avatar(result.getAvatar()).build();
    }

    /**
     * 目前只支持userName查
     *
     * @param py userName
     * @return
     */
    @Override
    public List<OrgTreeVo> selectUsersByPy(String py) {
        Result<List<SysUser>> sysUserResult = sysBaseAPI.queryByRealName(py);
        List<SysUser> result = sysUserResult.getResult();

        List<OrgTreeVo> list= new ArrayList<>();
        for (SysUser sysUser:result
             ) {
            OrgTreeVo user = OrgTreeVo.builder().name(sysUser.getRealname()).type("user").avatar(sysUser.getAvatar()).isLeader(!(sysUser.getDepartIds() == null)).id(sysUser.getId()).build();
            list.add(user);
        }
        return list;
    }

    @Override
    public List<OrgTreeVo> selectUsersByDept(String deptId) {
        Integer pageNo = 1;
        Integer pageSize = 100;
        List<OrgTreeVo> orgTreeVoList = new ArrayList<>();

        while (true) {
            Result<Map<String, Object>> result = sysBaseAPI.queryByDepId(pageNo, pageSize, deptId);
            Map<String, Object> resultMap = result.getResult();

            List<Map<String, Object>> records = (List<Map<String, Object>>) resultMap.get("records"); //集合
            int total = Integer.parseInt(resultMap.get("total").toString());

            for (Map<String, Object> obj : records) {

                String id = Optional.ofNullable(obj.get("id")).map(Object::toString).orElseGet(String::new);
                Boolean sex = Optional.ofNullable(obj.get("sex")).map(s -> Boolean.parseBoolean(s.toString())).orElse(null);
                String realname = Optional.ofNullable(obj.get("realname")).map(Object::toString).orElseGet(String::new);
                String avatar = Optional.ofNullable(obj.get("avatar")).map(Object::toString).orElseGet(String::new);
                String type = "user";
                OrgTreeVo orgTreeVo = OrgTreeVo.builder().id(id).name(realname).sex(sex).type(type).avatar(avatar).build();
                orgTreeVoList.add(orgTreeVo);
            }

            if (!(total > pageNo * pageSize)) {
                break;
            }
            pageNo++;
        }
        return orgTreeVoList;
    }

    @Override
    public List<UserDo> getUsersBatch(Collection<String> userIds) {
        String collect = String.join(",", userIds);
        Result<List<SysUser>> listResult = sysBaseAPI.queryUserByIds(collect);
        List<SysUser> result = listResult.getResult();

        return result.stream().map(sysUser -> UserDo.builder().userId(sysUser.getId()).userName(sysUser.getRealname()).avatar(sysUser.getAvatar()).build()).collect(Collectors.toList());

    }


    @Override
    public Set<String> getUsersByDepts(Collection<String> deptIds) {

        List<List<OrgTreeVo>> objects = new ArrayList<>();

        for (String deptId : deptIds) {
            List<OrgTreeVo> orgTreeVoList = selectUsersByDept(deptId);
            objects.add(orgTreeVoList);
        }

        return objects.stream().flatMap(List::stream).map(OrgTreeVo::getId).collect(Collectors.toSet());
    }


    /**
     * todo 目前部门只获取一个领导
     */
    @Override
    public DeptDo getDeptById(String deptId) {
        Result<SysDepartVO> sysDepartVOResult = sysBaseAPI.queryDeptById(deptId);
        SysDepartVO result = sysDepartVOResult.getResult();

        String onLeaderId = result.getLeader().get(0).getId();
        DeptDo deptDo = new DeptDo();
        deptDo.setId(result.getId());
        deptDo.setDeptName(result.getDeptName());
        deptDo.setParentId(result.getParentId());
        deptDo.setLeader(onLeaderId);

        return deptDo;
    }

    /**
     * 根据用户ID查询部门
     *
     * @param userId 用户ID
     * @return
     */
    @Override
    public List<DeptDo> getDeptsByUser(String userId) {
        Result<List<SysDepartVO>> listResult = sysBaseAPI.queryByUserId(userId);

        List<SysDepartVO> sysDepartVOS = listResult.getResult();

        return sysDepartVOS.stream().map(s -> {
            DeptDo deptDo = new DeptDo();
            deptDo.setId(s.getId());
            deptDo.setDeptName(s.getDeptName());
            deptDo.setParentId(s.getParentId());
            return deptDo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<DeptDo> getSysAllDepts() {
        System.out.println("自定义方法：getSysAllDepts ");
        Result<List<SysDepartVO>> result = sysBaseAPI.getAll();
        List<DeptDo> dos = result.getResult().stream()
                .map(d -> new DeptDo(d.getId(), d.getDeptName(), "", d.getParentId()))
                .collect(Collectors.toList());
        return dos;

    }

    /**
     * 查询所有的用户和对应的部门
     *
     * @return
     */
    @Override
    public List<UserDeptDo> getSysAllUserDepts() {
        //查所有部门
        Result<List<SysDepartVO>> listResult = sysBaseAPI.queryAll();
        List<SysDepartVO> departVOS = listResult.getResult();

        List<UserDeptDo> resuleList = new ArrayList<>();

        //根据部门Id  查用户
        for (SysDepartVO sysDepartVO : departVOS) {
            String deptId = sysDepartVO.getId();
            int pageNo = 1;
            int pageSize = 100;

            while (true) {

                Result<Map<String, Object>> result = sysBaseAPI.queryByDepId(pageNo, pageSize, deptId);
                Map<String, Object> resultMap = result.getResult();
                List<Map<String, Object>> records = (List<Map<String, Object>>) resultMap.get("records"); //集合
                int total = Integer.parseInt(resultMap.get("total").toString());

                List<UserDeptDo> userDeptDos = records.stream().map(s -> UserDeptDo.builder().deptId(deptId).userId(Optional.ofNullable(s.get("id")).map(Object::toString).orElseGet(String::new)).build()).collect(Collectors.toList());
                resuleList.addAll(userDeptDos);

                if (!(total > pageNo * pageSize)) {
                    break;
                }
                pageNo++;
            }

        }
        return resuleList;

    }

    @Override
    public List<OrgTreeVo> getSubDeptById(String parentId) {
        Result<List<SysDepartVO>> children = sysBaseAPI.getChildren(parentId);
        List<SysDepartVO> vos = children.getResult();
        List<OrgTreeVo> trees = new ArrayList<>();
        for (SysDepartVO vo : vos) {
            OrgTreeVo tree = OrgTreeVo.builder().id(vo.getId()).name(vo.getDeptName()).type("dept").build();
            trees.add(tree);
        }
        return trees;
    }


    @Override
    public List<String> getRecursiveSubDept(String parentId) {
        List<String> list = new ArrayList<>();
        loadSubDept(parentId, list);
        return list;
    }

    private void loadSubDept(String parentId, List<String> subDepts) {
        Result<List<SysDepartVO>> result = sysBaseAPI.getChildren(parentId);
        List<SysDepartVO> vos = result.getResult();
        subDepts.addAll(vos.stream().map(SysDepartVO::getId).collect(Collectors.toList()));
        vos.forEach(d -> loadSubDept(d.getId(), subDepts));
    }

    @Override
    public List<RoleDo> getSysAllRoles() {
        return defaultOrgRepositoryServiceImpl.getSysAllRoles();
    }

    @Override
    public Set<String> getUsersByRoles(List<String> roles) {
        return defaultOrgRepositoryServiceImpl.getUsersByRoles(roles);
    }
}
